package com.my.test.aop;

import java.util.Collection;
import java.util.List;

import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.defaults.DefaultSqlSession.StrictMap;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.my.test.common.DataSourceConst;
import com.my.test.common.DataSourceContextHolder;

@Aspect
@Component
public class DaoAop {

	@Autowired
	private SqlSessionFactory sqlSessionFactory;
	
	
	@Pointcut("execution(* com.my.test.dao.*.*(..))")
    private void httpUtilAspectPointCut(){};

    @Before("httpUtilAspectPointCut()")
    public void before()  {
    }

    @Around("httpUtilAspectPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Object result = null;
        System.out.println(getSQL(point));
        result = point.proceed();
        return result;
    }

    @After("httpUtilAspectPointCut()")
    public void after()  {
    }
    
    public String getSQL(ProceedingJoinPoint point){
    	String sqlString ="";
	    Object parameterObject =null;
    	try {
	       MethodSignature signature = (MethodSignature) point.getSignature();

	       //获取sql参数
	       MyMethodSignature method=new MyMethodSignature(sqlSessionFactory.getConfiguration(), signature.getMethod());
           Object tempParam = method.convertArgsToSqlCommandParam(point.getArgs());
           parameterObject = wrapCollection(tempParam);

	        Class<?>[] classz = point.getTarget().getClass().getInterfaces();  
            String sqlid = classz[0].getName()+"."+signature.getMethod().getName();  
	        //String sqlid=signature.getDeclaringTypeName()+"."+signature.getMethod().getName();
	        BoundSql boundSql= sqlSessionFactory.getConfiguration()
								.getMappedStatement(sqlid)
								.getBoundSql(parameterObject);
			sqlString=boundSql.getSql();
			String compareSql=sqlString.toLowerCase();
			System.out.println("打印的sql："+compareSql);
	        if (compareSql.indexOf("update")>=0||
	        		compareSql.indexOf("insert")>=0||
	        				compareSql.indexOf("delete")>=0||
	        						compareSql.indexOf("/*master*/")>=0
	    		) {
	        	System.out.println("====根据sql语句(update、insert、delete、/*master*/)切换数据源--为Master级别====");
	        	DataSourceContextHolder.setDataSourceType(DataSourceConst.writeDataSource);
			}else{
				System.out.println("====普通的sql====");
			}
	        
	        return LogDetailHelper.getSql(sqlSessionFactory.getConfiguration(),boundSql,parameterObject,sqlString);
		} catch (Exception e) {
			e.printStackTrace();
		}
    	return sqlString;
    }
    
    
    private Object wrapCollection(final Object object) {
        if (object instanceof Collection) {
          StrictMap<Object> map = new StrictMap<Object>();
          map.put("collection", object);
          if (object instanceof List) {
            map.put("list", object);
          }
          return map;
        } else if (object != null && object.getClass().isArray()) {
          StrictMap<Object> map = new StrictMap<Object>();
          map.put("array", object);
          return map;
        }
        return object;
      }
}
